﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace SHack
{
    class VarFile
    {
        private string _error;
        private SortedList<string, string[]> _slVar = new SortedList<string, string[]>();
        private SortedList<string, int> _slCursor = new SortedList<string, int>();
        private string[] _keys;

        public int Count
        {
            get { return _slVar.Count; }
        }
        
        public SortedList<string, string[]> List
        {
            get { return _slVar; }
        }

        public string[] Keys
        {
            get { return _slVar.Keys.ToArray<string>(); }
        }

        public int TotalCount
        {
            get {
                int ret = 1;
                foreach (string key in _slVar.Keys)
                {
                    ret *= _slVar[key].Length;
                }
                return ret;
            }
        }

        public string Error
        {
            get { return _error; }
        }

        public void Clear()
        {
            _keys = null;
            _slCursor.Clear();
            _slVar.Clear();
        }

        public VarFile Clone()
        {
            foreach (string key in _keys)
            {
                _slCursor[key] = 0;
            }
            return (VarFile)this.MemberwiseClone();
        }

        public SortedList<string, string> Get()
        {
            try
            {
                //完成了
                if (_slCursor[_keys[_keys.Length - 1]] >= _slVar[_keys[_keys.Length - 1]].Length)
                    return null;

                SortedList<string, string> sl = new SortedList<string, string>();

                foreach (string key in _keys)
                {
                    sl[key] = _slVar[key][_slCursor[key]];
                }

                Next(0);

                return sl;
            }
            catch (Exception ex)
            {
                Console.WriteLine("VarFile.cs->Get()", ex.Message);
            }

            return null;

        }

        public bool Next(int x)
        {
            try
            {

                if (x < _keys.Length)
                {
                    for (int i = x; i < _keys.Length; i++)
                    {
                        _slCursor[_keys[i]]++;
                        if (_slCursor[_keys[_keys.Length - 1]] >= _slVar[_keys[_keys.Length - 1]].Length)
                            return false;

                        if (_slCursor[_keys[i]] >= _slVar[_keys[i]].Length)
                        {
                            for (int j = 0; j <= i; j++)
                                _slCursor[_keys[j]] = 0;

                            if (!Next(i + 1))
                            {
                                return false;
                            }
                        }
                        else
                            return false;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("VarFile.cs->Next()", ex.Message);
            }
            return false;
        }

        public string Get(string text, SortedList<string, string> sl)
        {
            foreach (string key in sl.Keys)
            {
                text = text.Replace("{%" + key + "%}", sl[key]);
            }
            return text;
        }

        public bool IsVar(string text)
        {
            return new Regex(@"\{\%(.*?)\%\}").Match(text).Success;
        }

        public void AddVar(string str,string key=null)
        {

            if (str.Contains(","))
            {
                if (key == null)
                {
                    _slVar[str] = str.Split(',');
                    _slCursor[str] = 0;
                }
                else
                {
                    _slVar[key] = str.Split(',');
                    _slCursor[key] = 0;
                }
            }
            else if (str.Contains("."))
            {
                string filePath;

                if (str.Contains(":\\"))
                {
                    filePath = str;
                }
                else
                {
                    filePath = SysHelper.AppPath + str;
                }

                if (File.Exists(filePath))
                {
                    try
                    {
                        List<string> lt = new List<string>();
                        foreach (string r in File.ReadLines(filePath, Encoding.Default))
                        {
                            lt.Add(r);
                        }

                        if (key == null)
                        {
                            _slVar[str] = lt.ToArray();
                            _slCursor[str] = 0;
                        }
                        else
                        {
                            _slVar[key] = lt.ToArray();
                            _slCursor[key] = 0;
                        }
                    }
                    catch { }
                }
                else
                {
                    _error += "未找到变量" + str + "对应文件[" + filePath + "]！\r\n";
                }
            }
            else
            {
                if (key == null)
                {
                    _slVar[str] = new string[] { str };
                    _slCursor[str] = 0;
                }
                else
                {
                    _slVar[key] = new string[] { str };
                    _slCursor[key] = 0;
                }

            }

            _keys = _slCursor.Keys.ToArray<string>();
        }

        public bool AddMatch(string text)
        {
            Regex reg = new Regex(@"\{\%(.*?)\%\}");
            _error = "";

            MatchCollection mcs = reg.Matches(text);
            if(mcs.Count==0)
            {
                return true;
            }

            foreach (Match mc in mcs)
            {
                AddVar(mc.Groups[1].Value);
            }

            if (_slVar.Count != mcs.Count)
            {
                return false;
            }

            _keys = _slCursor.Keys.ToArray<string>();
            return true;        
        }

    }
}
